package com.ecoolex.chinadutyfree.retailer.admin.graphql;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.modularize.api.service.currency.CurrencyType;
import com.ecoolex.framework.modularize.api.service.currency.CurrencyTypeService;
import com.google.common.collect.Lists;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.alibaba.fastjson.JSONArray;
import com.ecoolex.chinadutyfree.retailer.admin.core.AdminConstant;
import com.ecoolex.chinadutyfree.retailer.entity.DeliveryManner;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrder;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderAfterSales;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderAfterSalesRecord;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderCoupon;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderDetail;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderIdentity;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderReceiver;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderSender;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderShippedRecord;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsBarcode;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsProduct;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsWithBLOBs;
import com.ecoolex.chinadutyfree.retailer.entity.PaymentOrder;
import com.ecoolex.chinadutyfree.retailer.enums.DirectMailGoodsOrderAfterSalesStatus;
import com.ecoolex.chinadutyfree.retailer.enums.DirectMailGoodsOrderStatus;
import com.ecoolex.chinadutyfree.retailer.pojo.AddDirectMailGoodsOrderShippedRecordDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.EditDirectMailGoodsOrderIdentityDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.EditDirectMailGoodsOrderReceiverDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.EditDirectMailGoodsOrderSenderDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.EditDirectMailGoodsOrderShippedRecordDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryDirectMailGoodsOrderAfterSalesDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryDirectMailGoodsOrderDTO;
import com.ecoolex.chinadutyfree.retailer.ws.DeliveryService;
import com.ecoolex.chinadutyfree.retailer.ws.DirectMailGoodsOrderService;
import com.ecoolex.chinadutyfree.retailer.ws.GoodsService;
import com.ecoolex.chinadutyfree.retailer.ws.PaymentOrderService;
import com.ecoolex.framework.common.annotation.Description;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.framework.modularize.api.service.region.Region;
import com.ecoolex.framework.modularize.api.service.region.RegionService;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;

@GraphQL2Module(type = Type.Admin, description = "直邮商品订单及售后管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY,
    key = DirectMailGoodsOrderGraphql.AUTH,
    name = "直邮商品订单及售后管理")
public class DirectMailGoodsOrderGraphql {

	public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-DIRECT-MAIL-GOODS-ORDER";
	
	@Reference
    private DirectMailGoodsOrderService orderService;
	
	@Autowired
    private ConsumerMemberManager consumerMemberManager;
	
	@Autowired
    private StorageService storageService;
	
	@Autowired
    private RegionService regionService;

	@Autowired
    private CurrencyTypeService currencyTypeService;
	
	@Reference
    private DeliveryService deliveryService;
	
	@Reference
	private PaymentOrderService paymentOrderService;
	
	@Reference
	private GoodsService goodsService;
	
	@TypeField(type = DirectMailGoodsOrderAfterSales.class,field = "afterSalesEvidenceImage",description = "售后单凭证图片")
	public List<StorageInfo> afterSalesEvidenceImage(@Source DirectMailGoodsOrderAfterSales source){
		String evidenceImage = source.getEvidenceImage();
		if(Check.notNull(evidenceImage)) {
			JSONArray jsonArray = JSONArray.parseArray(source.getEvidenceImage());
			List<String> list = jsonArray.toJavaList(String.class);
			return list.stream().map(storageId -> storageService.get(storageId)).collect(Collectors.toList());
		}
		return null;
	}
	
	@TypeField(type = DirectMailGoodsOrderAfterSalesRecord.class,field = "afterSalesRecordEvidenceImage",description = "售后记录凭证图片")
	public List<StorageInfo> afterSalesRecordEvidenceImage(@Source DirectMailGoodsOrderAfterSalesRecord source){
		String evidenceImage = source.getEvidenceImage();
		if(Check.notNull(evidenceImage)) {
			JSONArray jsonArray = JSONArray.parseArray(source.getEvidenceImage());
			List<String> list = jsonArray.toJavaList(String.class);
			return list.stream().map(storageId -> storageService.get(storageId)).collect(Collectors.toList());
		}
		return null;
	}
	
	@TypeField(type = DirectMailGoodsOrder.class, field = "paymentOrder", description = "支付信息")
	public PaymentOrder paymentOrder(@Source DirectMailGoodsOrder source) {
		return paymentOrderService.getByOrderNo(source.getOrderNo());
	}
	
	@TypeField(type = DirectMailGoodsOrder.class, field = "user", description = "用户信息")
    public ConsumerMember user(@Source DirectMailGoodsOrder source) {
        return consumerMemberManager.getByUserId(source.getUserId());
    }
	
    @TypeField(type = DirectMailGoodsOrder.class, field = "sender", description = "寄件人")
    public DirectMailGoodsOrderSender sender(@Source DirectMailGoodsOrder source) {
        return orderService.getSenderPossibleBeDeletedByOrderId(source.getOrderId());
    }

    @TypeField(type = DirectMailGoodsOrder.class, field = "receiver", description = "收件人")
    public DirectMailGoodsOrderReceiver receiver(@Source DirectMailGoodsOrder source) {
        return orderService.getReceiverPossibleBeDeletedByOrderId(source.getOrderId());
    }
    
    @TypeField(type = DirectMailGoodsOrder.class, field = "identity", description = "订单身份信息")
    public DirectMailGoodsOrderIdentity identity(@Source DirectMailGoodsOrder source) {
        return orderService.getIdentityPossibleBeDeletedByOrderId(source.getOrderId());
    }

    @TypeField(type = DirectMailGoodsOrderIdentity.class, field = "frontImage", description = "正面照片")
    public StorageInfo frontImage(@Source DirectMailGoodsOrderIdentity source) {
        return storageService.get(source.getFrontImage());
    }

    @TypeField(type = DirectMailGoodsOrderIdentity.class, field = "backImage", description = "背面")
    public StorageInfo backImage(@Source DirectMailGoodsOrderIdentity source) {
        return storageService.get(source.getBackImage());
    }

    @TypeField(type = DirectMailGoodsOrderReceiver.class, field = "region", description = "区域信息")
    public Region receiver(@Source DirectMailGoodsOrderReceiver source) {
        return regionService.get(source.getRegionId());
    }
    
    @TypeField(type = DirectMailGoodsOrder.class, field = "detailList", description = "订单详情")
    public List<DirectMailGoodsOrderDetail> detailList(@Source DirectMailGoodsOrder source) {
        return orderService.queryOrderDetailPossibleBeDeleted(source.getOrderId());
    }
    
    @TypeField(type = DirectMailGoodsOrderDetail.class, field = "goods", description = "商品")
    public GoodsWithBLOBs goods(@Source DirectMailGoodsOrderDetail source) {
    	return goodsService.getGoodsById(source.getGoodsId());
    }
    
    @TypeField(type = DirectMailGoodsOrderDetail.class, field = "goodsProduct", description = "产品")
    public GoodsProduct goodsProduct(@Source DirectMailGoodsOrderDetail source) {
    	return goodsService.getGoodsProductById(source.getProductId());
    }
    
    @TypeField(type = DirectMailGoodsOrderDetail.class, field = "goodsBarcodeList", description = "商品码")
    public List<GoodsBarcode> goodsBarcode(@Source DirectMailGoodsOrderDetail source) {
    	return goodsService.queryGoodsBarcodeByProductId(source.getProductId());
    }
    
    @TypeField(type = DirectMailGoodsOrder.class, field = "orderCouponList", description = "订单优惠券列表")
    public List<DirectMailGoodsOrderCoupon> orderCouponList(@Source DirectMailGoodsOrder source) {
        List<DirectMailGoodsOrderCoupon> orderCouponList = new ArrayList<>();
        orderService.queryOrderCouponByOrderId(source.getOrderId()).forEach(coupon -> {
            coupon.setDiscountAmount(coupon.getDiscountAmount().abs());
            orderCouponList.add(coupon);
        });
        return orderCouponList;
    }
    
    @TypeField(type = DirectMailGoodsOrderDetail.class, field = "image", description = "产品图片")
    public StorageInfo image(@Source DirectMailGoodsOrderDetail source) {
        return storageService.get(source.getImage());
    }
    
    @TypeField(type = DirectMailGoodsOrder.class, field = "currencyType", description = "币种")
    public CurrencyType currencyType(@Source DirectMailGoodsOrder source) {
        return currencyTypeService.get(source.getCurrencyType());
    }
    
    @TypeField(type = DirectMailGoodsOrder.class,field = "canRefund",description = "能主动给客户退款")
    public Boolean canRefund(@Source DirectMailGoodsOrder source) {
    	return DirectMailGoodsOrderStatus.canRefund(source.getStatus());
    }
	
    @TypeField(type = DirectMailGoodsOrderAfterSales.class,field = "directMailGoodsOrder",description = "售后单关联的订单")
    public DirectMailGoodsOrder directMailGoodsOrder(@Source DirectMailGoodsOrderAfterSales source) {
    	return orderService.getOrderById(source.getOrderId());
    }
 
	@TypeField(type = DirectMailGoodsOrder.class,field = "afterSales",description = "售后单")
	public DirectMailGoodsOrderAfterSales afterSales(@Source DirectMailGoodsOrder source) {
		return orderService.getDirectMailGoodsOrderAfterSalesByOrderId(source.getOrderId());
	}
	
	@TypeField(type = DirectMailGoodsOrderAfterSales.class,field = "canOperateRefund",description = "能处理售后单")
	public Boolean canOperateRefund(@Source DirectMailGoodsOrderAfterSales source) {
		return DirectMailGoodsOrderAfterSalesStatus.canOperationRefund(source.getStatus());
	}
	
	@TypeField(type = DirectMailGoodsOrderAfterSales.class,field = "canConfirmReceipt",description = "能确认收货")
	public Boolean canConfirmReceipt(@Source DirectMailGoodsOrderAfterSales source) {
		return DirectMailGoodsOrderAfterSalesStatus.canConfirmReceipt(source.getStatus());
	}
	
	@TypeField(type = DirectMailGoodsOrder.class,field = "afterSalesRecord",description = "售后记录列表")
	public List<DirectMailGoodsOrderAfterSalesRecord> afterSalesRecordList(@Source DirectMailGoodsOrder source){
		return orderService.afterSalesRecordListByOrderId(source.getOrderId());
	}
	
	@TypeField(type = DirectMailGoodsOrder.class, field = "shippedRecordList", description = "发货记录列表")
    public List<DirectMailGoodsOrderShippedRecord> shippedRecordList(@Source DirectMailGoodsOrder source) {
        return orderService.queryShippedRecordByOrderId(source.getOrderId());
    }

    @TypeField(type = DirectMailGoodsOrderShippedRecord.class, field = "deliveryManner", description = "配送方式")
    public DeliveryManner deliveryManner(@Source DirectMailGoodsOrderShippedRecord source) {
        return deliveryService.getDeliveryMannerById(source.getDeliveryMannerId());
    }

    //TODO: #8 后台发货管理
    @TypeField(type = DirectMailGoodsOrder.class, field = "canShipped", description = "是否能发货")
    public Boolean canShipped(@Source DirectMailGoodsOrder source) {
        return DirectMailGoodsOrderStatus.canShipped(source.getStatus());
    }

    //TODO: #8 后台发货管理
    @TypeField(type = DirectMailGoodsOrder.class, field = "canAddShippedRecord", description = "是否能添加发货记录")
    public Boolean canAddShippedRecord(@Source DirectMailGoodsOrder source) {
        return DirectMailGoodsOrderStatus.canEditShippedInfo(source.getStatus());
    }

    //TODO: #8 后台发货管理
    @TypeField(type = DirectMailGoodsOrder.class, field = "canDelShippedRecord", description = "是否能删除发货记录")
    public Boolean canDelShippedRecord(@Source DirectMailGoodsOrder source) {
        return DirectMailGoodsOrderStatus.canEditShippedInfo(source.getStatus());
    }

    //TODO: #8 后台发货管理
    @TypeField(type = DirectMailGoodsOrder.class, field = "canEditShippedRecordDetail", description = "是否能编辑发货记录详情")
    public Boolean canEditShippedRecordDetail(@Source DirectMailGoodsOrder source) {
        return DirectMailGoodsOrderStatus.canEditShippedInfo(source.getStatus());
    }
    //TODO: #8 后台发货管理
    @TypeField(type = DirectMailGoodsOrder.class, field = "canEditReceiver", description = "是否能修改收件人信息")
    public Boolean canEditReceiver(@Source DirectMailGoodsOrder source) {
        return DirectMailGoodsOrderStatus.canEditReceiver(source.getStatus());
    }

    //TODO: #8 后台发货管理
    @TypeField(type = DirectMailGoodsOrder.class, field = "canEditSender", description = "是否能操作寄件人信息")
    public Boolean canEditSender(@Source DirectMailGoodsOrder source) {
        return DirectMailGoodsOrderStatus.canEditSender(source.getStatus());
    }
	
	private static final String AUTH_GET = AUTH + "-GET";

    @QueryField(field = "directMailGoodsOrder",
        description = { "获取直销商品订单详情",
            "逻辑删除的一样可以查询到" })
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取商品订单详情")
    public DirectMailGoodsOrder get(@NonNull Integer orderId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_GET);
        return orderService.getOrderPossibleBeDeletedById(orderId);
    }

    private static final String AUTH_QUERY = AUTH + "-QUERY";

    @QueryField(field = "directMailGoodsOrderList", description = "查询商品订单列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询直销商品订单列表")
    public Pagination<DirectMailGoodsOrder> query(@NonNull QueryDirectMailGoodsOrderDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_QUERY);
        return orderService.query(query, sorts, page);
    }
    
    private static final String AUTH_AFTER_SALES_GET = AUTH + "-AFTER-SALES-GET";

    @QueryField(field = "directMailGoodsOrderAfterSales",
        description = { "获取商品售后单详情",
            "逻辑删除的一样可以查询到" })
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_AFTER_SALES_GET, name = "获取商品售后单详情")
    public DirectMailGoodsOrderAfterSales getAfterSales(@NonNull Integer afterSalesId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_AFTER_SALES_GET);
        return orderService.getAfterSalesPossibleBeDeletedByAfterSalesId(afterSalesId);
    }

    private static final String AUTH_AFTER_SALES_QUERY = AUTH + "-AFTER-SALES-QUERY";

    @QueryField(field = "directMailGoodsOrderAfterSalesList", description = "查询商品售后单列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_AFTER_SALES_QUERY, name = "查询商品售后单列表")
    public Pagination<DirectMailGoodsOrderAfterSales> queryAfterSales(@NonNull QueryDirectMailGoodsOrderAfterSalesDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertAuth(AUTH_AFTER_SALES_QUERY);
        return orderService.queryDirectMailGoodsOrderAfterSales(query, sorts, page);
    }
    
    private static final String AUTH_REFUND = AUTH + "-REFUND";

    @MutationField(field = "refundDirectMailGoodsOrder", description = "主动给用户直邮商品订单退款")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_REFUND, name = "主动给用户直邮商品订单退款")
    public DirectMailGoodsOrder refundDirectMailGoodsOrder(@NonNull Integer orderId,String reason, AdminMemberAuthority user) {
        user.assertAuth(AUTH_REFUND);
        DirectMailGoodsOrder order = orderService.getByOrderId(orderId);
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "商品订单不存在");
        return orderService.refund(order, reason, user.userName());
    }
	
	private static final String AUTH_REFUND_AGREE = AUTH + "-REFUND-AGREE";

    @MutationField(field = "confirmUserRefundDirectMailGoodsOrder", description = "同意用户直邮商品订单退款")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_REFUND_AGREE, name = "直邮商品订单用户退款申请")
    public DirectMailGoodsOrderAfterSales confirmRefundDirectMailGoodsOrder(@NonNull Integer afterSalesId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_REFUND_AGREE);
        DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
        return orderService.confirmRefund(afterSales, user.userName());
    }

    private static final String AUTH_REFUND_REFUSE = AUTH + "-REFUSE-REFUND";
    
    @MutationField(field = "refuseUserRefundDirectMailGoodsOrder", description = "拒绝用户直邮商品订单退款")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_REFUND_REFUSE, name = "拒绝用户直邮商品订单退款")
    public DirectMailGoodsOrderAfterSales cancelRefundDirectMailGoodsOrder(@NonNull Integer afterSalesId,@Description({"拒绝原因"}) String auditOpinion, AdminMemberAuthority user) {
        user.assertAuth(AUTH_REFUND_REFUSE);
        DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
        return orderService.refuseRefund(afterSales,auditOpinion, user.userName());
    }
    
    private static final String AUTH_RETURN_AGREE = AUTH + "-RETURN-AGREE";

    @MutationField(field = "agreeUserReturnDirectMailGoodsOrder", description = "同意用户直邮商品订单退货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_RETURN_AGREE, name = "同意用户直邮商品订单退货")
    public DirectMailGoodsOrderAfterSales agreeReturnDirectMailGoodsOrder(@NonNull Integer afterSalesId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_RETURN_AGREE);
        DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
        return orderService.confirmReturn(afterSales, user.userName());
    }

    private static final String AUTH_RETURN_REFUSE = AUTH + "-RETURN-REFUSE";
    
    @MutationField(field = "refuseUserReturnDirectMailGoodsOrder", description = "拒绝用户直邮商品订单退货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_RETURN_REFUSE, name = "拒绝用户直邮商品订单退货")
    public DirectMailGoodsOrderAfterSales refuseReturnDirectMailGoodsOrder(@NonNull Integer afterSalesId,@Description({"拒绝原因"}) String auditOpinion, AdminMemberAuthority user) {
        user.assertAuth(AUTH_RETURN_REFUSE);
        DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
        return orderService.refuseReturn(afterSales, auditOpinion, user.userName());
    }
    
    private static final String AUTH_EXCHANGE_AGREE = AUTH + "-EXCHANGE-AGREE";

    @MutationField(field = "agreeUserExchangeDirectMailGoodsOrder", description = "同意用户直邮商品订单换货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EXCHANGE_AGREE, name = "同意用户直邮商品订单换货")
    public DirectMailGoodsOrderAfterSales agreeExchangeDirectMailGoodsOrder(@NonNull Integer afterSalesId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EXCHANGE_AGREE);
        DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
        return orderService.confirmExchange(afterSales, user.userName());
    }

    private static final String AUTH_EXCHANGE_REFUSE = AUTH + "-EXCHANGE-REFUSE";
    
    @MutationField(field = "refuseUserExchangeDirectMailGoodsOrder", description = "拒绝用户直邮商品订单换货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EXCHANGE_REFUSE, name = "拒绝用户直邮商品订单换货")
    public DirectMailGoodsOrderAfterSales refuseExchangeDirectMailGoodsOrder(@NonNull Integer afterSalesId,@Description({"拒绝原因"}) String auditOpinion, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EXCHANGE_REFUSE);
        DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
        return orderService.refuseExchange(afterSales, auditOpinion, user.userName());
    }
    
    private static final String AUTH_CONFIRM_RECEIPT = AUTH + "-CONFIRM-RECEIPT";
    
    @MutationField(field = "confirmReceipt", description = "商户确认收货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_CONFIRM_RECEIPT, name = "商户确认收货")
    public DirectMailGoodsOrderAfterSales confirmReceipt(@NonNull Integer afterSalesId,AdminMemberAuthority user) {
    	user.assertAuth(AUTH_CONFIRM_RECEIPT);
    	DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
    	return orderService.confirmReceipt(afterSales, user.userName());
    }
    
    private static final String AUTH_REFUSE_RECEIPT = AUTH + "-REFUSE-RECEIPT";
    
    @MutationField(field = "refuseReceipt", description = "商户拒绝收货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_REFUSE_RECEIPT, name = "商户拒绝收货")
    public DirectMailGoodsOrderAfterSales refuseReceipt(@NonNull Integer afterSalesId,@NonNull String auditOpinion,AdminMemberAuthority user) {
    	user.assertAuth(AUTH_REFUSE_RECEIPT);
    	DirectMailGoodsOrderAfterSales afterSales = orderService.getDirectMailGoodsOrderAfterSalesByAfterSalesId(afterSalesId);
		Assert.isTrue(Check.notNull(afterSales),ResultCode.VERIFY.build(1), "商品订单售后单不存在");
    	return orderService.refuseReceipt(afterSales,auditOpinion, user.userName());
    }

    private static final String AUTH_SHIPPED = AUTH + "-SHIPPED";
    //TODO: #8 后台发货管理
    @MutationField(field = "shippedDirectMailGoodsOrder", description = "直邮商品订单发货")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_SHIPPED, name = "直邮商品订单发货")
    public DirectMailGoodsOrder shippedDirectMailGoodsOrder(@NonNull Integer orderId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_SHIPPED);
        DirectMailGoodsOrder order = orderService.getOrderById(orderId);
        Assert.isTrue(Check.notNull(order), ResultCode.VERIFY.build(1), "订单不存在");
        return orderService.shipped(order, user.userName());
    }
    
    private static final String AUTH_ADD_SHIPPED_RECORD = AUTH + "-ADD-SHIPPED-RECORD";

    //TODO: #8 后台发货管理
    @MutationField(field = "addDirectMailGoodsOrderShippedRecord",description = { "添加直邮商品发货记录"})
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD_SHIPPED_RECORD, name = "添加直邮商品发货记录")
    public DirectMailGoodsOrderShippedRecord addDirectMailGoodsOrderShippedRecord(@NonNull Integer orderId, @NonNull AddDirectMailGoodsOrderShippedRecordDTO add, @NonNull List<Integer> detailIdList, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ADD_SHIPPED_RECORD);
        DirectMailGoodsOrder order = orderService.getOrderById(orderId);
        Assert.isTrue(Check.notNull(order), ResultCode.VERIFY.build(1), "订单不存在");

        return orderService.addShippedRecord(order, add, detailIdList, user.userName());
    }

    private static final String AUTH_EDIT_SHIPPED_RECORD = AUTH + "-EDIT-SHIPPED-RECORD";
    
    //TODO: #8 后台发货管理
    @MutationField(field = "editDirectMailGoodsOrderShippedRecord",description = { "编辑直邮商品发货记录"})
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT_SHIPPED_RECORD, name = "编辑直邮商品发货记录")
    public DirectMailGoodsOrderShippedRecord editDirectMailGoodsOrderShippedRecord(@NonNull EditDirectMailGoodsOrderShippedRecordDTO edit, @NonNull List<Integer> detailIdList, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT_SHIPPED_RECORD);
        DirectMailGoodsOrderShippedRecord old = orderService.getShippedRecordById(edit.getShippedRecordId());
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "发货记录不存在");

        BeanUtil.copy(edit,
                old,
                Lists.newArrayList(DirectMailGoodsOrderShippedRecord.Column.orderId,
                        DirectMailGoodsOrderShippedRecord.Column.deleted,
                        DirectMailGoodsOrderShippedRecord.Column.createUser,
                        DirectMailGoodsOrderShippedRecord.Column.createTime).stream().map(
                        DirectMailGoodsOrderShippedRecord.Column::getJavaProperty).toArray(String[]::new));

        return orderService.updateShippedRecord(old, detailIdList, user.userName());
    }

    private static final String AUTH_DEL_SHIPPED_RECORD = AUTH + "-DEL-SHIPPED-RECORD";
    
    //TODO: #8 后台发货管理
    @MutationField(field = "delDirectMailGoodsOrderShippedRecord",description = { "删除直邮商品发货记录"})
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL_SHIPPED_RECORD, name = "删除直邮商品发货记录")
    public boolean delDirectMailGoodsOrderShippedRecord(@NonNull Integer shippedRecordId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_DEL_SHIPPED_RECORD);
        DirectMailGoodsOrderShippedRecord record = orderService.getShippedRecordById(shippedRecordId);
        Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "发货记录不存在");
        orderService.deleteShippedRecord(record, user.userName());
        return true;
    }

    private static final String AUTH_EDIT_RECEIVER = AUTH + "-EDIT-RECEIVER";

    //TODO: #8 后台发货管理
    @MutationField(field = "editReceiver", description = "直邮商品订单修改收件人信息")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT_RECEIVER, name = "直邮商品订单修改收件人信息")
    public DirectMailGoodsOrderReceiver editReceiver(@NonNull EditDirectMailGoodsOrderReceiverDTO dto, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT_RECEIVER);
        DirectMailGoodsOrderReceiver old = orderService.getReceiverByOrderId(dto.getOrderId());
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "收件人信息不存在");
        BeanUtil.copy(dto,
                old,
                Lists.newArrayList(DirectMailGoodsOrderReceiver.Column.deleted, 
	                	DirectMailGoodsOrderReceiver.Column.createUser, 
	                	DirectMailGoodsOrderReceiver.Column.createTime).stream().map(
                		DirectMailGoodsOrderReceiver.Column::getJavaProperty).toArray(String[]::new));
        return orderService.updateReceiver(old, user.userName());
    }
    
    private static final String AUTH_EDIT_IDENTITY = AUTH + "-EDIT-IDENTITY";
    
    @MutationField(field = "editIdentity", description = "修改直邮商品订单身份信息")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT_IDENTITY, name = "修改直邮商品订单身份信息")
    public DirectMailGoodsOrderIdentity editIdentity(@NonNull EditDirectMailGoodsOrderIdentityDTO dto, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT_IDENTITY);
        DirectMailGoodsOrderIdentity old = orderService.getIdentityByOrderId(dto.getOrderId());
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "身份信息不存在");
        BeanUtil.copy(dto,
                old,
                Lists.newArrayList(DirectMailGoodsOrderIdentity.Column.deleted,
	                	DirectMailGoodsOrderIdentity.Column.createUser, 
	                	DirectMailGoodsOrderIdentity.Column.createTime).stream().map(
                		DirectMailGoodsOrderIdentity.Column::getJavaProperty).toArray(String[]::new));
        return orderService.updateDirectMailGoodsOrderIdentity(old, user.userName());
    }

    private static final String AUTH_ADD_SENDER = AUTH + "-ADD-SENDER";

    //TODO: #8 后台发货管理
    @MutationField(field = "addSender", description = "直邮商品订单新增寄件人信息")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD_SENDER, name = "直邮商品订单新增寄件人信息")
    public DirectMailGoodsOrderSender addSender(@NonNull EditDirectMailGoodsOrderSenderDTO dto, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ADD_SENDER);
        return orderService.addSender(dto, user.userName());
    }

    private static final String AUTH_EDIT_SENDER = AUTH + "-EDIT-SENDER";

    //TODO: #8 后台发货管理
    @MutationField(field = "editSender", description = "直邮商品订单修改寄件人信息")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT_SENDER, name = "直邮商品订单修改寄件人信息")
    public DirectMailGoodsOrderSender editSender(@NonNull EditDirectMailGoodsOrderSenderDTO dto, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT_SENDER);
        DirectMailGoodsOrderSender old = orderService.getSenderByOrderId(dto.getOrderId());
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "寄件人信息不存在");
        BeanUtil.copy(dto,
                old,
                Lists.newArrayList(DirectMailGoodsOrderSender.Column.deleted, 
	                	DirectMailGoodsOrderSender.Column.createUser, 
	                	DirectMailGoodsOrderSender.Column.createTime).stream().map(
                		DirectMailGoodsOrderSender.Column::getJavaProperty).toArray(String[]::new));
        return orderService.updateSender(old, user.userName());
    }

    private static final String AUTH_DEL_SENDER = AUTH + "-DEL-SENDER";

    //TODO: #8 后台发货管理
    @MutationField(field = "deleteSender", description = "直邮商品订单删除寄件人信息")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL_SENDER, name = "直邮商品订单删除寄件人信息")
    public Boolean deleteSender(@NonNull Integer id, AdminMemberAuthority user) {
        user.assertAuth(AUTH_DEL_SENDER);
        DirectMailGoodsOrderSender sender = orderService.getSenderByOrderId(id);
        Assert.isTrue(Check.notNull(sender), ResultCode.VERIFY.build(1), "寄件人信息不存在");
        orderService.deleteSender(sender, user.userName());
        return true;
    }
    
    @MutationField(field = "uploadDirectMailGoodsOrderIdentityFrontImage", description = { "上传直邮商品身份证正面" })
    public StorageInfo uploadDirectMailGoodsOrderIdentityFrontImage(@NonNull Upload request, AdminMemberAuthority user) {
    	UploadSource uploadSource = new UploadSource("DirectMailGoodsOrderIdentity", "FrontImage");

        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(20));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }

    @MutationField(field = "uploadDirectMailGoodsOrderIdentityBackImage", description = { "上传直邮商品身份证反面" })
    public StorageInfo uploadDirectMailGoodsOrderIdentityBackImage(@NonNull Upload request, AdminMemberAuthority user) {
    	UploadSource uploadSource = new UploadSource("DirectMailGoodsOrderIdentity", "BackImage");

        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(20));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }
}
